import { Destroyable, react } from "xbsj-xe2/dist-node/xe2-base-utils";
import { MyProjectManager } from '../../MyProjectManager';
import { actorType, viewType, floorMapItem } from "../dataTypes";
import { ESUnrealActor } from "esobjs-xe2-plugin/dist-node/esobjs-xe2-plugin-main";
export class Building extends Destroyable {
    public name = ""
    // 建筑楼层
    public floorMap = new Map()
    // 每层高亮外壳
    public highlightMap = new Map()
    // 楼层和每层高亮外壳的映射关系
    public map: floorMapItem[] = []
    // 定时器
    public intervalTime: any = null
    // 楼层展开状态
    public status: 'shrink' | 'expand' | 'expanding' | 'shrinking' = 'shrink';
    // 步长
    public steps: number = 100
    // 总时长
    public time: number = 2
    // 楼层特效
    public effect: ESUnrealActor | undefined
    // 当前楼层
    public currentFloor: string = "all"
    constructor(private myProjectManager: MyProjectManager) {
        super();
    }
    /**
     * 数据更新
     * @param buildData 
     * @param highLightData 
     * @param map 
     */
    setData(buildData: actorType[], highLightData: actorType[], map: floorMapItem[], effect: actorType) {
        this.effect = this.myProjectManager.createSceneObjectFromJson(effect.sceneObj)
        this.map = map
        // 楼宇建筑
        buildData.forEach((data, index) => {
            const { id, actorTag, name, position, rotation } = data.sceneObj
            const e = this.myProjectManager.createSceneObject(ESUnrealActor, id)
            if (!e) return
            e.name = name
            e.actorTag = actorTag
            e.position = position
            e.rotation = rotation
            this.floorMap.set(id, e)
            const item = this.map.find(item => item.floorId == id)
            if (!item) return
            item.currentPosition = JSON.parse(JSON.stringify(position))
            item.startPosition = JSON.parse(JSON.stringify(position))
            item.endPosition = JSON.parse(JSON.stringify(id == "canting_louti" ? position : [position[0], position[1], position[2] + 4 * index]))

        })
        // 高亮外壳
        highLightData.forEach(data => {
            const { id, actorTag, name, position, rotation } = data.sceneObj
            const e = this.myProjectManager.createSceneObject(ESUnrealActor, id)
            if (!e) return
            e.name = name
            e.actorTag = actorTag
            e.position = position
            e.rotation = rotation
            e.collision = false
            e.allowPicking = false
            e.show = false
            this.highlightMap.set(id, e)
        })

    }

    /**
     * 楼层展开
     * @param expand 展开/收缩
     * @returns 
     */
    toggleFloor(expand: boolean, during: number = 2, levelIndex: number = -1, hiddenLevel: boolean = false) {
        let promise = new Promise((resolve, reject) => {
            // 避免重复点击
            if (((this.status == 'expanding' || this.status == 'expand') && expand) || ((this.status == 'shrinking' || this.status == 'shrink') && !expand)) {
                resolve("")
                return
            }
            if (this.intervalTime) clearInterval(this.intervalTime)
            // 时间
            this.time = during

            if (during == 0) {
                this.map.forEach(item => {
                    const sceneObj = this.floorMap.get(item.floorId)
                    const highlight = this.highlightMap.get(item.highlightId)
                    if (!sceneObj) return
                    sceneObj.show = true
                    const endPosition = expand ? item.endPosition : item.startPosition
                    if (endPosition) {
                        sceneObj.position = endPosition
                        highlight.position = endPosition
                    }
                })
                this.status = expand ? 'expand' : 'shrink'
                resolve("")
                return
            }
            const interTime = this.time * 1000 / this.steps;
            // 线性插值
            function linearInterpolate(start: number, end: number, t: number) {
                return start + (end - start) * t;
            }
            let currentStep = 0;
            // 获取当前位置
            this.map.forEach(item => {
                const sceneObj = this.floorMap.get(item.floorId)
                item.currentPosition = JSON.parse(JSON.stringify(sceneObj?.position))
            })
            this.intervalTime = setInterval(() => {
                this.status = expand ? 'expanding' : 'shrinking'
                this.map.forEach((item, index) => {
                    if (index > levelIndex) {
                        // 场景对象
                        const sceneObj = this.floorMap.get(item.floorId)
                        // 高亮对象
                        const highlight = this.highlightMap.get(item.highlightId)
                        // 楼层显示
                        sceneObj.show = true
                        if (currentStep >= this.steps && index > levelIndex) {
                            sceneObj.show = !hiddenLevel
                        }
                        // 插值起点
                        const startPosition = item.currentPosition
                        // 插值终点
                        const endPosition = expand ? item.endPosition : item.startPosition
                        if (startPosition && endPosition) {
                            if (currentStep < this.steps) {
                                const t = currentStep / this.steps; // 插值因子，从0到1
                                // 计算插值后的经度、纬度和高度
                                const interpolatedLongitude = linearInterpolate(startPosition[0], endPosition[0], t);
                                const interpolatedLatitude = linearInterpolate(startPosition[1], endPosition[1], t);
                                const interpolatedHeight = linearInterpolate(startPosition[2], endPosition[2], t);
                                // 输出插值后的点
                                if (sceneObj) sceneObj.position = [interpolatedLongitude, interpolatedLatitude, interpolatedHeight];
                                if (highlight) highlight.position = [interpolatedLongitude, interpolatedLatitude, interpolatedHeight];
                            } else {
                                if (sceneObj) sceneObj.position = endPosition
                                if (highlight) highlight.position = endPosition
                            }

                        }
                    }
                });

                if (currentStep >= this.steps) {
                    clearInterval(this.intervalTime); // 停止插值
                    this.intervalTime = undefined
                    this.status = expand ? 'expand' : 'shrink'
                    resolve("")
                }
                currentStep++;
            }, interTime)
        })
        return promise
    }

    /**
     * 高亮楼层
     * @param floorId 
     * @returns 
     */
    setFloorHighLight(floorId: string, status: 'Normal' | 'Warning' | 'none' = 'Normal') {
        const item = this.map.find(item => item.floorId == floorId)
        if (!item) return
        const highlight = this.highlightMap.get(item.highlightId)
        if (highlight) {
            if (status == 'none') {
                highlight.show = false
            } else {
                highlight.show = true
                highlight.callFunction('SetSelectBoxStatus', { Status: status })
            }

        }
    }
    /**
     * 设置全部楼层高亮显/隐
     * @param show 
     */
    setAllFloorsHighlight(show: boolean = true) {
        this.map.forEach(item => {
            const highlight = this.highlightMap.get(item.highlightId)
            const floor = this.floorMap.get(item.floorId)
            if (highlight) {
                if (floor) highlight.position = floor.position
                highlight.callFunction('SetSelectBoxStatus', { Status: 'Normal' })
                highlight.show = show
            }
        })
    }

    /**
     * 设置单层显示楼层
     * @param floorId 
     * @returns 
     */
    setFloorVisible(floorId: string, view: viewType) {
        if (this.currentFloor == 'all') {
            const index = this.map.findIndex(item => item.floorId == floorId)
            this.toggleFloor(true, 1, index, true).then(() => {
                const { position, rotation } = view
                this.myProjectManager.activeViewer?.flyIn(position, rotation, 1)
            })
        } else {
            const floor = this.map.find(item => item.floorId == floorId)
            if (!floor) return
            this.map.forEach(item => {
                const sceneObj = this.floorMap.get(item.floorId)
                if (sceneObj) sceneObj.show = (item.index <= floor.index)
            })
            const { position, rotation } = view
            this.myProjectManager.activeViewer?.flyIn(position, rotation, 1)
        }

        this.currentFloor = floorId
    }


    /**
     * 设置建筑的显隐
     * @param show 
     */
    setBuildVisible(show: boolean = true) {
        this.floorMap.forEach(item => item.show = show)
    }

    /**
     * 设置室内的高度尺寸
     * @param scale 
     */
    setInsideScaleZ(scale: number) {
        this.floorMap.forEach(item => {
            try {
                item.callFunction('SetInsideScale', { Scale: scale })
            } catch (error) {
            }
        })
    }

    /**
     * 设置建筑特效
     * @param show 
     */
    setBuildEffect(show: boolean) {
        if (this.effect) {
            this.effect.show = show
        }
    }

    /**
     * 恢复楼层原始位置
     */
    recoverBuild() {
        this.map.forEach(item => {
            const sceneObj = this.floorMap.get(item.floorId)
            if (sceneObj) {
                sceneObj.position = item.startPosition
                sceneObj.show = true
            }

            const highlight = this.highlightMap.get(item.highlightId)
            if (highlight) highlight.position = item.startPosition
        })
    }




}